package com.haircut.project.service.record.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haircut.project.constant.RecordConstant;
import com.haircut.project.dao.category.ProjectCategoryMapper;
import com.haircut.project.dao.config.ProjectConfigMapper;
import com.haircut.project.dao.group.ProjectGroupConfigRelMapper;
import com.haircut.project.dao.record.ProjectRecordMapper;
import com.haircut.project.dao.record.RecordProjectMapper;
import com.haircut.project.model.category.ProjectCategory;
import com.haircut.project.model.config.ProjectConfig;
import com.haircut.project.model.group.ProjectGroupConfigRel;
import com.haircut.project.model.record.ProjectRecord;
import com.haircut.project.model.record.RecordProject;
import com.haircut.project.service.record.IRecordService;
import com.haircut.project.utils.excel.ExceUtils;
import com.haircut.project.utils.record.RecordUtils;
import com.haircut.project.vo.record.*;
import com.haircut.project.vo.record.excel.RecordResExcelVo;
import com.haircut.project.vo.statistics.*;
import com.haircut.sys.dao.dept.SyDeptMapper;
import com.haircut.sys.dao.user.SysUserMapper;
import com.haircut.sys.model.dept.SysDept;
import com.haircut.sys.model.user.SysUser;
import com.haircut.sys.service.dept.IDeptService;
import com.haircut.sys.service.permission.IPermissionService;
import com.haircut.sys.utils.PageUtils;
import com.haircut.sys.utils.user.SecurityUtils;
import com.haircut.sys.vo.dept.DeptSimpleVo;
import com.haircut.sys.vo.server.server.Sys;
import com.haircut.sys.vo.user.LoginUserVo;
import com.modular.constant.BaseCodeDesc;
import com.modular.constant.NumberConstant;
import com.modular.exception.ModularException;
import com.modular.result.PageResult;
import com.modular.utils.DBUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RecordServiceImpl implements IRecordService {
    @Autowired
    private ProjectRecordMapper projectRecordMapper;
    @Autowired
    @Qualifier("modularSnowflake")
    private Snowflake snowflake;
    @Autowired
    private ProjectConfigMapper projectConfigMapper;
    @Autowired
    private ProjectCategoryMapper projectCategoryMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private IPermissionService permissionService;
    @Autowired
    private SyDeptMapper syDeptMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ProjectGroupConfigRelMapper projectGroupConfigRelMapper;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private RecordProjectMapper recordProjectMapper;

    /**
     * 保存记录信息
     *
     * @param recordVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRecord(ApiRecordVo recordVo) {

        recordVo.setTotalCardAmount(Optional.ofNullable(recordVo.getTotalCardAmount()).orElse(BigDecimal.ZERO));
        recordVo.setTotalCashAmount(Optional.ofNullable(recordVo.getTotalCashAmount()).orElse(BigDecimal.ZERO));
        recordVo.setDiscountAmount(Optional.ofNullable(recordVo.getDiscountAmount()).orElse(BigDecimal.ZERO));

        if(StrUtil.isBlank(recordVo.getCardRemark()) && ObjectUtil.isNotNull(recordVo.getTotalCardAmount()) && recordVo.getTotalCardAmount().doubleValue() > NumberConstant.ZERO){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "有电子金额，必须填写流水号");
        }
        String recordId = snowflake.nextIdStr();
        List<ProjectConfig> configList = this.queryConfig(recordVo.getProjects());
        BigDecimal configTotalAmount = BigDecimal.ZERO;
        List<RecordProject> recordProjectList = new ArrayList<>(configList.size());
        RecordProject project = null;
        for(ProjectConfig config:configList){
            configTotalAmount = configTotalAmount.add(config.getProjectAmount());
            project = new RecordProject();
            project.setId(snowflake.nextIdStr());
            project.setRecordId(recordId);
            project.setConfigId(config.getId());
            project.setCategoryId(config.getCategoryId());
            project.setConfigName(config.getProjectName());
            project.setConfigAmount(config.getProjectAmount());
            recordProjectList.add(project);
        }
        if(configTotalAmount.doubleValue() < recordVo.getDiscountAmount().doubleValue()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "优惠金额不能大于总金额");
        }
        LoginUserVo loginUserVo = SecurityUtils.getLoginUser();
        SysUser sysUser = userMapper.selectById(loginUserVo.getUserId());
        // 去掉优惠的总金额
        BigDecimal realAmount = configTotalAmount.subtract(recordVo.getDiscountAmount());
        // 小费金额
        BigDecimal tipAmount = BigDecimal.ZERO;
        // 统计收入金额
        BigDecimal totalAmount = recordVo.getTotalCardAmount().add(recordVo.getTotalCashAmount());
        if(totalAmount.doubleValue() < realAmount.doubleValue()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "收费金额和配置的总金额不匹配");
        }
        ProjectRecord record = new ProjectRecord();
        record.setIncomeCardAmount(recordVo.getTotalCardAmount());
        record.setIncomeCashAmount(recordVo.getTotalCashAmount());

        // 如果总金额小于电子入账金额，则需要给小费
        BigDecimal diffAmount = realAmount;
        if(recordVo.getTotalCardAmount().doubleValue() > NumberConstant.ZERO){
            // 计算差值
            tipAmount = recordVo.getTotalCardAmount().subtract(realAmount);
            // 如果电子收费小于总金额，则需要计算现金金额
            if(tipAmount.doubleValue() <= NumberConstant.ZERO) {
                diffAmount = realAmount.subtract(recordVo.getTotalCardAmount());
                tipAmount = BigDecimal.ZERO;
            }else{
                recordVo.setTotalCardAmount(recordVo.getTotalCardAmount().subtract(tipAmount));
                // 如果电子收费大于总金额，则现金收费为0
                diffAmount = BigDecimal.ZERO;
            }
        }
        recordVo.setTotalCashAmount(diffAmount);

        Date currDate = DateUtil.date();
        BigDecimal technicianRate = sysUser.getTechnicianRate();
        BigDecimal techCashAmount = RecordUtils.calcAmountRate(recordVo.getTotalCashAmount(),technicianRate);
        BigDecimal techCardAmount = RecordUtils.calcAmountRate(recordVo.getTotalCardAmount(),technicianRate);

        BeanUtils.copyProperties(recordVo, record);
        record.setId(recordId);
        record.setCardRemark(recordVo.getCardRemark());
        record.setTechnicianRate(technicianRate);
        record.setDeptId(loginUserVo.getDeptId());
        record.setTotalAmount(configTotalAmount);
        record.setDiscountAmount(record.getDiscountAmount());
        record.setTechCardAmount(techCardAmount);
        record.setTechCashAmount(techCashAmount);
        record.setTotalCardAmount(recordVo.getTotalCardAmount());
        record.setTotalCashAmount(recordVo.getTotalCashAmount());
        record.setCompanyCashAmount(record.getTotalCashAmount().subtract(record.getTechCashAmount()));
        record.setCompanyCardAmount(record.getTotalCardAmount().subtract(record.getTechCardAmount()));
        record.setTipsCardAmount(tipAmount);
        record.setCreateDate(currDate);
        record.setModifyDate(currDate);
        record.setCreateUserId(loginUserVo.getUserId());
        record.setModifyUserId(loginUserVo.getUserId());
        record.setRecordType(RecordConstant.RecordType.NEW_RECORD);
        projectRecordMapper.insert(record);

        this.batchSaveRecordConfig(recordProjectList,recordId);
    }

    private void batchSaveRecordConfig(List<RecordProject> recordProjectList,String recordId){
        LambdaQueryWrapper<RecordProject> query = Wrappers.lambdaQuery();
        query.eq(RecordProject::getRecordId,recordId);
        recordProjectMapper.delete(query);

        recordProjectMapper.batcInsert(recordProjectList);
    }

    private List<ProjectConfig> queryConfig(List<ApiRecordProjectVo> projectVoList){
        List<String> configIdList = projectVoList.stream().map(ApiRecordProjectVo::getConfigId).filter(Objects::nonNull).toList();
        if(configIdList.size() != projectVoList.size()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"记录信息错误");
        }
        List<ProjectConfig> configList = projectConfigMapper.selectBatchIds(configIdList);
        if(ObjectUtil.isNull(configList) || configIdList.size() != configList.size()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"记录信息错误");
        }
        return configList;

    }

    /**
     * 保存记录信息
     *
     * @param recordVo
     */
    @Override
    public void moidfyRecord(ApiRecordVo recordVo) {
        if (StrUtil.isBlank(recordVo.getId())) {
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "记录id不正确");
        }
        ProjectRecord record = projectRecordMapper.selectById(recordVo.getId());
        if (ObjectUtil.isNull(record)) {
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "记录id不正确");
        }
        if (ObjectUtil.notEqual(record.getRecordType(), RecordConstant.RecordType.NEW_RECORD)) {
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "已经核查的数据不能修改");
        }
        List<ProjectConfig> configList = this.queryConfig(recordVo.getProjects());
        BigDecimal configTotalAmount = BigDecimal.ZERO;
        List<RecordProject> recordProjectList = new ArrayList<>(configList.size());
        RecordProject project = null;
        for(ProjectConfig config:configList){
            configTotalAmount = configTotalAmount.add(config.getProjectAmount());
            project = new RecordProject();
            project.setId(snowflake.nextIdStr());
            project.setRecordId(record.getId());
            project.setConfigId(config.getId());
            project.setCategoryId(config.getCategoryId());
            project.setConfigName(config.getProjectName());
            project.setConfigAmount(config.getProjectAmount());
            recordProjectList.add(project);
        }
        if(configTotalAmount.doubleValue() < recordVo.getDiscountAmount().doubleValue()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "优惠金额不能大于总金额");
        }

        LoginUserVo loginUserVo = SecurityUtils.getLoginUser();
        SysUser sysUser = userMapper.selectById(loginUserVo.getUserId());

        recordVo.setTotalCardAmount(Optional.ofNullable(recordVo.getTotalCardAmount()).orElse(BigDecimal.ZERO));
        recordVo.setTotalCashAmount(Optional.ofNullable(recordVo.getTotalCashAmount()).orElse(BigDecimal.ZERO));
        recordVo.setDiscountAmount(Optional.ofNullable(recordVo.getDiscountAmount()).orElse(BigDecimal.ZERO));
        if(StrUtil.isBlank(recordVo.getCardRemark()) && ObjectUtil.isNotNull(recordVo.getTotalCardAmount()) && recordVo.getTotalCardAmount().doubleValue() > NumberConstant.ZERO){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "有电子金额，必须填写流水号");
        }
        // 去掉优惠的总金额
        BigDecimal realAmount = configTotalAmount.subtract(recordVo.getDiscountAmount());
        // 小费金额
        BigDecimal tipAmount = BigDecimal.ZERO;
        // 统计收入金额
        BigDecimal totalAmount = recordVo.getTotalCardAmount().add(recordVo.getTotalCashAmount());
        if(totalAmount.doubleValue() < realAmount.doubleValue()){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "收费金额和配置的总金额不匹配");
        }
        BigDecimal incomeCardAmount = recordVo.getTotalCardAmount();
        BigDecimal incomeCashAmount = recordVo.getTotalCashAmount();

        // 如果总金额小于电子入账金额，则需要给小费
        BigDecimal diffAmount = realAmount;
        if(recordVo.getTotalCardAmount().doubleValue() > NumberConstant.ZERO){
            // 计算差值
            tipAmount = recordVo.getTotalCardAmount().subtract(realAmount);
            // 如果电子收费小于总金额，则需要计算现金金额
            if(tipAmount.doubleValue() <= NumberConstant.ZERO) {
                diffAmount = realAmount.subtract(recordVo.getTotalCardAmount());
                tipAmount = BigDecimal.ZERO;
            }else{
                recordVo.setTotalCardAmount(recordVo.getTotalCardAmount().subtract(tipAmount));
                // 如果电子收费大于总金额，则现金收费为0
                diffAmount = BigDecimal.ZERO;
            }
        }

        recordVo.setTotalCashAmount(diffAmount);
        BigDecimal technicianRate = sysUser.getTechnicianRate();
        BigDecimal techCashAmount = RecordUtils.calcAmountRate(recordVo.getTotalCashAmount(),technicianRate);
        BigDecimal techCardAmount = RecordUtils.calcAmountRate(recordVo.getTotalCardAmount(),technicianRate);


        LambdaUpdateWrapper<ProjectRecord> modify = Wrappers.lambdaUpdate();
        modify.set(ProjectRecord::getTotalCashAmount, recordVo.getTotalCashAmount());
        modify.set(ProjectRecord::getTotalCardAmount, recordVo.getTotalCardAmount());
        modify.set(ProjectRecord::getCustName, recordVo.getCustName());
        modify.set(ProjectRecord::getModifyDate, DateUtil.date()).set(ProjectRecord::getModifyUserId, SecurityUtils.getUserId());
        modify.set(ProjectRecord::getDiscountAmount, recordVo.getDiscountAmount());
        modify.set(ProjectRecord::getCardRemark,recordVo.getCardRemark());
        modify.set(ProjectRecord::getTotalAmount,configTotalAmount);
        modify.set(ProjectRecord::getIncomeCardAmount,incomeCardAmount);
        modify.set(ProjectRecord::getIncomeCashAmount,incomeCashAmount);
        modify.set(ProjectRecord::getTechCardAmount,techCardAmount)
                .set(ProjectRecord::getTechCashAmount,techCashAmount);
        modify.set(ProjectRecord::getCompanyCashAmount,recordVo.getTotalCashAmount().subtract(techCashAmount))
                .set(ProjectRecord::getCompanyCardAmount,recordVo.getTotalCardAmount().subtract(techCardAmount));
        modify.set(ProjectRecord::getRecordRemark,recordVo.getRecordRemark());
        modify.set(ProjectRecord::getTipsCardAmount,tipAmount);
        modify.set(ProjectRecord::getTechnicianRate,technicianRate);
        modify.eq(ProjectRecord::getId, record.getId());
        projectRecordMapper.update(modify);

        this.batchSaveRecordConfig(recordProjectList,record.getId());

    }



    /**
     * 分页查询数据
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<RecordResVo> findManagerPage(RecordReqVo reqVo)
    {
        if(ObjectUtil.isNotNull(reqVo.getStatTime())){
            reqVo.setStatTime(DateUtil.beginOfDay(reqVo.getStatTime()));
        }
        if(ObjectUtil.isNotNull(reqVo.getEndTime()) ){
            reqVo.setEndTime(DateUtil.endOfDay(reqVo.getEndTime()));
        }
        if(ObjectUtil.isNull(reqVo.getStatTime())){
            Date date = DateUtil.date();
            reqVo.setStatTime(DateUtil.beginOfDay(DateUtil.offsetMonth(date,-3)));
            reqVo.setEndTime(DateUtil.endOfDay(date));
        }
        reqVo.setUserName(DBUtils.escapeQuryLikeParam(reqVo.getUserName()));
        reqVo.setDataScopeList(permissionService.findPermissionSqlList("t.create_user_id","t.dept_id"));
        IPage<?> reqPage = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<RecordResVo> page = projectRecordMapper.findManagerPage(reqPage,reqVo);
        if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
            return PageUtils.cover(reqVo);
        }
        List<String> recordIdList = page.getRecords().stream().map(RecordResVo::getId).toList();
        List<SysUser> userList = userMapper.selectBatchIds(page.getRecords().stream().map(RecordResVo::getCreateUserId).distinct().toList());
        Map<String,SysUser> userMap = userList.stream().collect(Collectors.toMap(SysUser::getId,p->p));
        SysUser sysUser = null;
        Map<String,List<RecordProjectVo>> map = findRecordProjectByRecordIdList(recordIdList);
        for(RecordResVo resVo:page.getRecords()){
            sysUser = userMap.get(resVo.getCreateUserId());
            resVo.setCreateUserName(sysUser.getRealName());
            resVo.setProjectList(map.get(resVo.getId()));
        }
        page.getRecords().add(projectRecordMapper.findManagerStatic(reqVo));

        return  PageUtils.cover(page);
    }

    /**
     * 导出数据
     * @param reqVo
     * @param res
     */
    public void export(RecordReqVo reqVo, HttpServletResponse res)
    {
        if(ObjectUtil.isNotNull(reqVo.getStatTime())){
            reqVo.setStatTime(DateUtil.beginOfDay(reqVo.getStatTime()));
        }
        if(ObjectUtil.isNotNull(reqVo.getEndTime()) ){
            reqVo.setEndTime(DateUtil.endOfDay(reqVo.getEndTime()));
        }
        if(ObjectUtil.isNull(reqVo.getStatTime())){
            Date date = DateUtil.date();
            reqVo.setStatTime(DateUtil.beginOfDay(DateUtil.offsetMonth(date,-3)));
            reqVo.setEndTime(DateUtil.endOfDay(date));
        }
        reqVo.setUserName(DBUtils.escapeQuryLikeParam(reqVo.getUserName()));
        reqVo.setDataScopeList(permissionService.findPermissionSqlList("t.create_user_id","t.dept_id"));
        boolean hasNext = Boolean.TRUE;
        IPage<?> reqPage = null;
        int currPage =0,pageSize = NumberConstant.FIVE * NumberConstant.HUNDRED;
        Page<RecordResVo> page = null;
        SysUser sysUser = null;
        List<RecordResExcelVo> excelVoList = new ArrayList<>();
        RecordResExcelVo excelVo = null;
        while(hasNext){
            currPage ++;
            reqPage = Page.of(currPage,pageSize);
            page = projectRecordMapper.findManagerPage(reqPage,reqVo);
            if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
                break;
            }
            if(page.getRecords().size() < pageSize){
                hasNext = Boolean.FALSE;
            }
            List<SysUser> userList = userMapper.selectBatchIds(page.getRecords().stream().map(RecordResVo::getCreateUserId).distinct().toList());
            Map<String,SysUser> userMap = userList.stream().collect(Collectors.toMap(SysUser::getId,p->p));
            for(RecordResVo resVo:page.getRecords()){
                sysUser = userMap.get(resVo.getCreateUserId());
                resVo.setCreateUserName(sysUser.getRealName());
                excelVo = new RecordResExcelVo();
                BeanUtils.copyProperties(resVo,excelVo);
                excelVo.formt(resVo.getRecordType());
                excelVoList.add(excelVo);
            }

        }
        writeExcel(excelVoList,res);


    }
    private void writeExcel(List<RecordResExcelVo> excelVoList,HttpServletResponse res){
        try{
            String fileName = snowflake.nextIdStr();
            res.setContentType(MediaType.ALL_VALUE);
            res.setCharacterEncoding("utf-8");
            res.addHeader("Content-Disposition", "attachment;filename="+fileName+".xlsx");
            ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(res.getOutputStream(),RecordResExcelVo.class);
            excelWriterBuilder.registerWriteHandler(ExceUtils.getHorizontalCellStyleStrategy());
            excelWriterBuilder.autoCloseStream(Boolean.TRUE).sheet("记录").doWrite(excelVoList);

        }catch (Exception e){

        }
    }

    private Map<String,List<RecordProjectVo>> findRecordProjectByRecordIdList(List<String> recordIdList){
        LambdaQueryWrapper<RecordProject> query = Wrappers.lambdaQuery();
        query.in(RecordProject::getRecordId,recordIdList);
        List<RecordProject> dbList = recordProjectMapper.selectList(query);
        List<String> cateIdList = dbList.stream().map(RecordProject::getCategoryId).distinct().toList();
        List<ProjectCategory> catList = projectCategoryMapper.selectBatchIds(cateIdList);
        Map<String,ProjectCategory> categoryMap = catList.stream().collect(Collectors.toMap(ProjectCategory::getId,p->p));

        List<RecordProjectVo> voList = new ArrayList<>(dbList.size());
        RecordProjectVo projectVo = null;
        ProjectCategory category = null;
        for(RecordProject project:dbList){
            projectVo = new RecordProjectVo();
            BeanUtils.copyProperties(project,projectVo);
            category = categoryMap.get(project.getCategoryId());
            projectVo.setCategoryName(category.getCategoryName());
            voList.add(projectVo);
        }

        return voList.stream().collect(Collectors.groupingBy(RecordProjectVo::getRecordId));
    }


    /**
     * 分页查询数据
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<ApiRecordResVo> findPage(ApiRecordReqVo reqVo)
    {
        IPage<?> reqPage = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<ApiRecordResVo> page = projectRecordMapper.findPage(reqPage,reqVo);
        if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
            return PageUtils.cover(reqVo);
        }
        return  PageUtils.cover(page);
    }

    /**
     * 查询详情
     * @param id
     * @return
     */
    @Override
    public ApiRecordDetailVo findDetail(String id){
        ProjectRecord record = projectRecordMapper.selectById(id);
        ApiRecordDetailVo resVo = new ApiRecordDetailVo();
        BeanUtils.copyProperties(record,resVo);
        resVo.setTotalCardAmount(resVo.getTotalCardAmount().add(resVo.getTipsCardAmount()));
        LambdaQueryWrapper<RecordProject> query = Wrappers.lambdaQuery();
        query.eq(RecordProject::getRecordId,id);
        List<RecordProject> list = recordProjectMapper.selectList(query);
        List<ApiRecordProjectVo> projects = new ArrayList<>(list.size());
        ApiRecordProjectVo projectVo = null;
        for(RecordProject project:list){
            projectVo = new ApiRecordProjectVo();
            BeanUtils.copyProperties(project,projectVo);
            projects.add(projectVo);
        }
        resVo.setProjects(projects);
        return resVo;
    }

    /**
     * 核查数据
     * @param recordId
     */
    @Override
    public void checkRecord(String recordId)
    {
        ProjectRecord record = projectRecordMapper.selectById(recordId);
        if(ObjectUtil.isNull(record)){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG, "记录id不正确");
        }
        LambdaUpdateWrapper<ProjectRecord> modify = Wrappers.lambdaUpdate();
        modify.set(ProjectRecord::getRecordType, RecordConstant.RecordType.CHECK_RECORD);
        modify.set(ProjectRecord::getModifyDate,DateUtil.date()).set(ProjectRecord::getModifyUserId,SecurityUtils.getUserId());
        modify.set(ProjectRecord::getCheckDate,DateUtil.date()).set(ProjectRecord::getCheckUserId,SecurityUtils.getUserId());

        modify.eq(ProjectRecord::getId,record.getId());
        projectRecordMapper.update(modify);

    }

    /**
     * 查询统计数据
     * @return
     */
    @Override
    public List<SalaryDeptResVo> findSalaryStatic()
    {

        Date currDate = DateUtil.date();
        List<String> dataScopeList = permissionService.findPermissionSqlList("t.create_user_id","t.dept_id");
        SalaryReqVo reqVo = new SalaryReqVo();
        reqVo.setStartDate(DateUtil.beginOfDay(currDate));
        reqVo.setEndDate(DateUtil.endOfDay(currDate));
        reqVo.setDataScopeList(dataScopeList);
        List<SalayResVo>  currList  = projectRecordMapper.findSalaryStatic(reqVo);
        currList.forEach(p->{
            p.setStaticProject("今日");
        });
        Map<String,SalayResVo> currMap = currList.stream().collect(Collectors.toMap(SalayResVo::getDeptId,p->p));
        List<String> deptIdList = new ArrayList<>(currMap.keySet());


        Date yestdate = DateUtil.yesterday();
        reqVo.setStartDate(DateUtil.beginOfDay(yestdate));
        reqVo.setEndDate(DateUtil.endOfDay(yestdate));
        reqVo.setDataScopeList(dataScopeList);
        List<SalayResVo>  yesList  = projectRecordMapper.findSalaryStatic(reqVo);
        yesList.forEach(p->{
            p.setStaticProject("昨日");
        });
        Map<String,SalayResVo> yesMap = yesList.stream().collect(Collectors.toMap(SalayResVo::getDeptId,p->p));
        deptIdList.addAll(yesMap.keySet());

        Date startDate = DateUtil.offsetDay(currDate,-6);
        reqVo.setStartDate(DateUtil.beginOfDay(startDate));
        reqVo.setEndDate(DateUtil.endOfDay(yestdate));
        reqVo.setDataScopeList(dataScopeList);
        List<SalayResVo>  senvenList  = projectRecordMapper.findSalaryStatic(reqVo);
        senvenList.forEach(p->{
            p.setStaticProject("近7日");
        });
        Map<String,SalayResVo> senvenMap = senvenList.stream().collect(Collectors.toMap(SalayResVo::getDeptId,p->p));
        deptIdList.addAll(senvenMap.keySet());
        deptIdList = deptIdList.stream().distinct().toList();
        if(CollUtil.isEmpty(deptIdList)){
            return Collections.emptyList();
        }
        List<SalaryDeptResVo> resVoList = new ArrayList<>();
        List<SysDept> deptList = syDeptMapper.selectBatchIds(deptIdList);
        SalaryDeptResVo resVo = null;
        List<SalayResVo> itemList = null;
        SalayResVo itemVo;
        for(SysDept dept:deptList){
            resVo = new SalaryDeptResVo();
            resVo.setDeptName(dept.getDeptName());
            itemList = new ArrayList<>();
            itemVo = currMap.get(dept.getId());
            if(ObjectUtil.isNull(itemVo)){
                itemVo = new SalayResVo();
                itemVo.init();
                itemVo.setStaticProject("今日");
            }
            itemList.add(itemVo);

            itemVo = yesMap.get(dept.getId());
            if(ObjectUtil.isNull(itemVo)){
                itemVo = new SalayResVo();
                itemVo.init();
                itemVo.setStaticProject("昨日");
            }
            itemList.add(itemVo);
            itemVo = senvenMap.get(dept.getId());
            if(ObjectUtil.isNull(itemVo)){
                itemVo = new SalayResVo();
                itemVo.init();
                itemVo.setStaticProject("近7日");
            }
            itemList.add(itemVo);
            resVo.setResVoList(itemList);
            resVoList.add(resVo);
        }


        return resVoList;
    }

    /**
     * 项目排行榜
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<StatisProjectVo> findProjectRankPage(SalaryReqVo reqVo){
        reqVo.setDataScopeList(permissionService.findPermissionSqlList("t.create_user_id","t.dept_id"));
        IPage<?> pageReq = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<StatisProjectVo> page = projectRecordMapper.findProjectRankPage(pageReq,reqVo);
        if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
            return PageUtils.cover(reqVo);
        }
        return PageUtils.cover(page);
    }

    /**
     * 用户排行榜
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<StatsUserVo> findUserRankPage(SalaryReqVo reqVo)
    {
        reqVo.setDataScopeList(permissionService.findPermissionSqlList("t.create_user_id","t.dept_id"));
        IPage<?> pageReq = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<StatsUserVo> page = projectRecordMapper.findUserRankPage(pageReq,reqVo);
        if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
            return PageUtils.cover(reqVo);
        }
        List<String> userIdList = page.getRecords().stream().map(StatsUserVo::getUserId).distinct().toList();
        List<SysUser> userList =  userMapper.selectBatchIds(userIdList);
        List<String> deptIdList = userList.stream().map(SysUser::getDeptId).distinct().toList();
        Map<String,SysUser> userMap = userList.stream().collect(Collectors.toMap(SysUser::getId,p->p));
        Map<String, DeptSimpleVo> deptMap =deptService.findDeptMapByDeptIdList(deptIdList);
        SysUser sysUser = null;
        DeptSimpleVo deptSimpleVo = null;
        for(StatsUserVo userVo:page.getRecords()){
            sysUser = userMap.get(userVo.getUserId());
            userVo.setUserName(sysUser.getRealName());
            deptSimpleVo = deptMap.get(sysUser.getDeptId());
            userVo.setDeptName(deptSimpleVo.getDeptName());
        }

        return PageUtils.cover(page);
    }

}
